home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FishMarket 1.0
/
FishMarket v1.0.iso
/
fishies
/
151-175
/
disk_160
/
dwip
/
dwip.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-06
|
22KB
|
858 lines
/* dwip.c: Daisy Wheel IFF Printer utility.
* Placed in the public domain by the author:
* Ken Van Camp
* Digitized Data Display Systems
* P.O. Box 878
* Marshalls Creek, PA 18335-0878
* Version 1.0 March 12, 1988
* Based heavily on the public domain jiff and plop programs by Jim Kent
*/
#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/libraries.h>
#include <graphics/gfx.h>
#include <graphics/rastport.h>
#include <graphics/text.h>
#include <intuition/intuition.h>
#include <stdio.h>
#include "jiff.h"
#define PARANOID
/* variables specific to dwip: */
typedef float REAL;
struct dev_info {
REAL hpitch, vpitch, /* horizontal & vertical dot pitch (dpi) */
hlength, vlength; /* horiz & vert length of tot pic (inches) */
int xstart, ystart, /* starting position (in dots) */
xstop, ystop, /* stopping position (in dots) */
width, height; /* area to print (in dots) */
};
struct dev_info scr = { /* screen device info */
XMAX/10.25, /* hpitch */
YMAX/7.15, /* vpitch */
0., 0., /* hlength, vlength (computed, not initialized) */
0, 0, /* xstart, ystart */
0, 0, /* xstop, ystop (computed, not initialized) */
XMAX, YMAX /* width, height */
};
struct dev_info ptr = { /* printer device info */
10., /* hpitch */
6., /* vpitch */
0., 0., /* hlength, vlength (computed, not initialized) */
0, 0, /* xstart, ystart (unused on printer) */
0, 0, /* xstop, ystop (unused on printer) */
135, /* width (135 columns of text) */
0 /* height (computed, not initialized) */
};
REAL hreduce, /* reduction factor (dots per dot) screen to ptr */
vreduce, /* same, but vertical */
r_intens = 1.0, /* red color intensity */
g_intens = 0.7, /* green color intensity */
b_intens = 1.0; /* blue color intensity */
int fileopen=0, /* is an output file open? */
sideopt=0, /* print it sideways? */
dotopt=0, /* use dots instead of characters? */
viewopt=0, /* view only (don't print)? */
modopt=0, /* modify (invert) the image? */
autopt=1, /* automatically start up background printing? */
nplanes, /* # bitplanes used in this picture */
ncolors, /* # colors in the pallette */
universal=0, /* "universal" printing option (use backspaces) */
testpat=0, /* just print a test pattern? */
scrn_alloc=0; /* has a screen been allocated? */
/* these are the RGB components of all the colors in the palette: */
unsigned short rcol[MAXCOL], gcol[MAXCOL], bcol[MAXCOL];
FILE *outfile, *fopen(); /* output file descriptor */
char *bplane[PLANES], /* ptrs to each bitplane */
*filename, /* output file name */
init_string[160] = "", /* initialization string to printer */
eol_string[20] = "\n"; /* end-of-line string */
/* following is for the line buffers. Each buffer holds one line of
* data to be output to the printer, separated by a carriage return
*/
#define NBUFS 6 /* max #chars can be overstruck for 1 dot */
char buf[NBUFS][XMAX]; /* buffers for line output */
int buf_used[NBUFS]; /* flag: was buffer used in this line? */
char *documentation[] = {
"dwip: public domain Daisy Wheel IFF Printer utility v1.0 by Ken Van Camp",
" usage: dwip [options] files --where valid options are:",
" -lval set leftmost location on screen (default 0)",
" -tval set top location on screen (default 0)",
" -wval set width of screen area to print (default 320)",
" -hval set height of screen area to print (default 200)",
" -pval set printer pitch (default 10)",
" -cval set # columns to use across printer (default 135)",
" -nval set # lines per inch on printer (default 6)",
" -istring set initialization string (default is none)",
" -estring set end-of-line string (default is newline)",
" -ofile send output to named file (default is RAM:dwXXXX)",
" -s toggle to print sideways (default OFF)",
" -m toggle to modify (negative) picture (default OFF)",
" -rval set red relative intensity (default 1.0)",
" -gval set green relative intensity (default 0.7)",
" -bval set blue relative intensity (default 1.0)",
" -vtime view file for time seconds, instead of printing",
0 };
/* Following are strings to send for each of the 37 character grey scales.
* This table came from:
* "Considerations for Efficient Picture Output via Lineprinter"
* by Peter Henderson and Steven Tanimoto, Computer Graphics & Image
* Processing, Vol 3. 1974, pp. 327-335.
*/
#define MAXSHADES 37
char *letters[MAXSHADES] = {
/* 0 next */
"MW#O0+",
"MW#O0 ",
"MW#O+ ",
"MW#0 ",
"MW#O ",
"MW# ",
"MW0 ",
"MWO ",
"H#+ ",
"H#- ",
/* 10 next */
"H# ",
"H* ",
"H+ ",
"X+ ",
"H- ",
"X- ",
"O- ",
"Z- ",
"W ",
"M ",
/* 20 next */
"N ",
"H ",
"0 ",
"O ",
"S ",
"== ",
"I ",
"* ",
"+- ",
"+ ",
/* 30 next */
"= ",
": ",
"-- ",
". ",
"- ",
"` ",
" " };
struct ILBM_info *s_info;
/*This should be in exec/libraries.h */
extern struct Library *OpenLibrary();
/*This should be in intuition/intuition.h */
extern struct Screen *OpenScreen();
struct Library *GfxBase = NULL;
struct Library *LayersBase = NULL;
struct Library *IntuitionBase = NULL;
struct Screen *DwipScreen = NULL;
struct TextAttr DwipFont =
{
"topaz.font", /* I think this is the ROM font */
8,
0,
0,
};
/* a NewScreen - I don't know what half of this means either */
static
struct NewScreen DwipNewScreen =
{
0, 0, XMAX, YMAX, PLANES,
0, 1,
0,
CUSTOMSCREEN,
&DwipFont,
"dwip dwip dwip",
NULL,
NULL,
};
/* To use clip blit need a RastPort. */
struct RastPort DwipRastPort;
/* help: Give good help */
void help (hp)
char **hp;
{
void dwip_cleanup();
register char **dp;
for (dp = hp; *dp; dp++)
printf ("%s\n", *dp);
dwip_cleanup();
exit(1);
} /* help */
/*put_ea_cmap given an ea-type color map:
an array of unsigned chars of form ea_cmap[] = {r, g, b, r, g, b...}
turn it into an amiga-type color map:
an array of unsigned short of form amiga_cmap = {0xrgb, 0xrgb, ...}
and then tell Dale these are the colors we want for our viewport */
void put_ea_cmap(cmap, colors)
unsigned char *cmap;
int colors;
{
unsigned short amy_cmap[MAXCOL];
int i;
unsigned char r, g, b;
if (colors > MAXCOL) /*color clipping*/
colors = MAXCOL;
ncolors = colors;
for (i=0; i<colors; i++){
rcol[i] = (cmap[0] & 0xf0) >> 4;
gcol[i] = (cmap[1] & 0xf0) >> 4;
bcol[i] = (cmap[2] & 0xf0) >> 4;
amy_cmap[i] = ((cmap[0] & 0xf0) << 4) + (cmap[1] & 0xf0) +
((cmap[2] & 0xf0) >> 4);
cmap += 3;
}
LoadRGB4( &DwipScreen->ViewPort, amy_cmap, (long)colors);
} /* put_ea_cmap */
/* back out backwards */
void dwip_cleanup()
{
if (DwipScreen != NULL)
CloseScreen(DwipScreen);
if (IntuitionBase != NULL)
CloseLibrary(IntuitionBase);
if (LayersBase != NULL)
CloseLibrary(LayersBase);
if (GfxBase != NULL)
CloseLibrary(GfxBase);
if (fileopen){
fileopen = 0;
fclose (outfile);
}
if (scrn_alloc){
scrn_alloc = 0;
free_planes (&s_info->bitmap);
}
} /* dwip_cleanup */
/* getbit: return value (0 or 1) of specified bit of supplied byte.
* Why didn't I put this in a macro?
*/
int getbit (b, n)
char b;
int n;
{
return (b>>n & 1);
} /* getbit */
/* get_shade: return the shade of the specified pixel */
int get_shade (x, y)
int x, y; /* coords of the pixel */
{
int color_num, /* color number of the pixel */
j, /* index to bitplanes */
shade, /* shade of the pixel */
byte_num, /* byte # offset within bitplane */
bit; /* bit # within byte */
char *b; /* actual byte address */
byte_num = y * 40 + x / 8;
bit = 7 - (x % 8); /* bits are in reverse order! */
/* find color # */
color_num = 0;
for (j = 0; j < nplanes; j++){
b = bplane[j] + (char *)byte_num;
color_num += getbit (*b, bit) << j;
}
if (color_num > ncolors){
#ifdef PARANOID
printf ("Unknown color #%d\n", color_num);
#endif PARANOID
return(0);
}else{
shade = (int) ((REAL)rcol[color_num] * r_intens +
(REAL)gcol[color_num] * g_intens +
(REAL)bcol[color_num] * b_intens);
if (modopt)
/* inverse picture */
return (MAXSHADES - shade);
else
/* normal picture */
return (shade);
} /* if color_num */
} /* get_shade */
/* charshade: Returns the string of characters to send to produce a given
* shade of grey.
*/
char *charshade (shade)
int shade;
{
if (shade < MAXSHADES)
return (letters[shade]);
else
/* This makes more pixels white than really should be. */
return (letters[MAXSHADES-1]);
}
/* set_values: Set the screen printing parameters. This routine is called
* before every picture is printed, in case anything has changed since
* the last picture.
*/
void set_values ()
{
if (scr.xstart < 0)
scr.xstart = 0;
if (scr.ystart < 0)
scr.ystart = 0;
if (scr.width + scr.xstart > XMAX)
scr.width = XMAX - scr.xstart;
if (scr.height + scr.ystart > YMAX)
scr.height = YMAX - scr.ystart;
ptr.hlength = ptr.width / ptr.hpitch;
scr.hlength = scr.width / scr.hpitch;
scr.vlength = scr.height / scr.vpitch;
if (! sideopt){
/* normal print */
hreduce = (REAL) scr.width / ptr.width;
ptr.vlength = scr.vlength * ptr.hlength / scr.hlength;
}else{
/* sideways print */
hreduce = (REAL) scr.height / ptr.width;
ptr.vlength = scr.hlength * ptr.hlength / scr.hlength;
}
ptr.height = ptr.vlength * ptr.vpitch;
vreduce = (REAL) scr.height / ptr.height;
scr.xstop = scr.xstart + scr.width - 1;
scr.ystop = scr.ystart + scr.height - 1;
#ifdef DEBUG
printf("Screen : pitches=%lf,%lf lengths=%lf,%lf width=%d height=%d\n",
scr.hpitch, scr.vpitch, scr.hlength, scr.vlength, scr.width,
scr.height);
printf("Printer: pitches=%lf,%lf lengths=%lf,%lf width=%d height=%d\n",
ptr.hpitch, ptr.vpitch, ptr.hlength, ptr.vlength, ptr.width,
ptr.height);
printf("reduce=%lf,%lf start=%d,%d stop=%d,%d\n", hreduce, vreduce,
scr.xstart, scr.ystart, scr.xstop, scr.ystop);
#endif
} /* set_values */
/* eval_strg: evaluate 3-digit decimal constants within a string */
void eval_strg (s)
char *s;
{
int i, j;
char t[80], tmp[4];
tmp[3] = NULL;
i = j = 0;
while (s[i] != NULL){
if (s[i] == '\\'){
/* decode a decimal constant */
tmp[0] = s[++i];
tmp[1] = s[++i];
tmp[2] = s[++i];
t[j++] = (char) atoi (tmp);
}else
t[j++] = s[i];
i++;
}
t[j] = NULL;
strcpy (s, t);
} /* eval_strg */
/* eval_arg: Evaluate a command-line argument, and set appropriate global
* variables. Returns 1 if just an input filename, 0 if a valid option.
* Doesn't return at all if an invalid option.
*/
int eval_arg (arg)
char *arg;
{
void help(), eval_strg();
double atof();
int i, /* char array index */
optused; /* flag: was complete option used? */
char c; /* next char to process */
if (arg[0] == '-'){
/* cmmd line option: interpret */
i = 1;
optused = 0; /* could be more than one option per minus sign */
c = arg[i];
/* do until delimiter between arguments is found: either a space
* or null
*/
while (c && c != ' ' && !optused){
i++;
switch (c){
case '?':
help (documentation);
break;
case 'a': /* auto-printing option */
autopt = !autopt;
break;
case 'b': /* set blue value */
b_intens = atof (&arg[i]);
optused++;
break;
case 'c': /* set # columns on printer */
ptr.width = atoi (&arg[i]);
optused++;
break;
case 'd': /* dot (dithering) option */
dotopt = !dotopt;
printf ("Dot option not implemented yet\n");
break;
case 'e': /* end-of-line string */
/* sprintf (eol_string, &arg[i]); */
strcpy (eol_string, &arg[i]);
eval_strg (eol_string);
optused++;
break;
case 'g': /* set green value */
g_intens = atof (&arg[i]);
optused++;
break;
case 'h': /* set screen height */
scr.height = atoi (&arg[i]);
optused++;
break;
case 'i': /* initialization string */
/* sprintf (init_string, &arg[i]); */
strcpy (init_string, &arg[i]);
eval_strg (init_string);
optused++;
break;
case 'l': /* set left edge of screen to print */
scr.xstart = atoi (&arg[i]);
optused++;
break;
case 'm': /* set "modified" flag (inverse image) */
modopt = !modopt;
break;
case 'n': /* set # lines per inch on printer */
ptr.vpitch = atoi (&arg[i]);
optused++;
break;
case 'o': /* output filename */
/* strcpy (filename, &arg[i]); */
filename = &arg[i];
optused++;
if (fileopen){
fclose (outfile);
fileopen = 0;
}
break;
case 'p': /* set printer pitch */
ptr.hpitch = atoi (&arg[i]);
optused++;
break;
case 'r': /* set red value */
r_intens = atof (&arg[i]);
optused++;
break;
case 's': /* print sideways option */
sideopt = !sideopt;
break;
case 't': /* set top edge of screen to print */
scr.ystart = atoi (&arg[i]);
optused++;
break;
case 'u': /* universal printing option (use backspaces) */
universal = 1;
break;
case 'v': /* view file option */
viewopt = atoi (&arg[i]);
autopt = 0; /* turns off auto-printing option */
optused++;
break;
case 'w': /* set screen width */
scr.width = atoi (&arg[i]);
optused++;
break;
case 'z': /* just print test pattern */
testpat = 1;
break;
default:
printf ("Unknown option %c\n", c);
help (documentation);
} /* switch (c) */
c = arg[i];
} /* while */
return (0);
}else
/* Just a file name */
return (1);
} /* eval_arg */
/* init_graph: Initialize Amiga graphics */
int init_graph()
{
if ((GfxBase = OpenLibrary("graphics.library", (long)0)) == NULL){
printf("Can't open Graphics Library\n");
return(1);
}
if ((LayersBase = OpenLibrary("layers.library", (long)0)) == NULL){
printf("Can't open Layers Library\n");
dwip_cleanup();
return(2);
}
if ((IntuitionBase = OpenLibrary("intuition.library",(long)0)) == NULL){
printf("Can't open Intuition Library\n");
dwip_cleanup();
return(3);
}
if ( (DwipScreen = OpenScreen(&DwipNewScreen) ) == NULL){
printf("OpenScreen failed\n");
dwip_cleanup();
return(4);
}
InitRastPort(&DwipRastPort);
DwipRastPort.Mask = (1<<PLANES)-1; /*just play it safe in case someone
* tries to load 6 bit planes...*/
return(0);
} /* init_graph */
/* outstring: Store a character string in the output buffers.
* One buffer is used per overstriked character.
*/
void outstring (s, nchar)
char *s; /* string of chars to be overlaid */
int nchar; /* current position in buffers */
{
int i; /* buffer # */
for (i = 0; i < NBUFS; i++)
if ((buf[i][nchar] = s[i]) != ' ')
buf_used[i] = 1;
} /* outstring */
/* printscreen: This routine sends out the characters to the printer */
void printscreen()
{
char *charshade();
void dwip_cleanup(), outstring();
int get_shade();
int j, /* index to bitplanes */
i, /* index to buffers */
ct, /* count of #chars outputted on line */
shade, /* shade of a pixel */
x, y; /* actual screen coord looked at */
REAL xskip, yskip; /* # pixels skipped since last one printed */
if (! fileopen){
if ((outfile = fopen (filename, "w")) == NULL){
printf("Couldn't open file %s for output\n", filename);
help (documentation);
}
fileopen = 1;
}
/* initialize the bitplane pointers */
nplanes = s_info->bitmap.Depth;
for (j=0; j < s_info->bitmap.Depth; j++)
bplane[j] = (char *)s_info->bitmap.Planes[j];
fprintf(outfile,"%s", init_string);
/* want normal or sideways print? */
if (! sideopt){
/* normal printout */
for (y = scr.ystart, yskip = 0.; y <= scr.ystop; y++){
yskip += 1.;
while (yskip > vreduce){
/* plot this line */
yskip -= vreduce;
/* Initialize the line buffers */
for (i = 0; i < NBUFS; i++)
buf_used[i] = 0;
for (x=scr.xstart, xskip=0., ct=0; x <= scr.xstop; x++){
xskip += 1.;
while (xskip > hreduce){
/* plot this pixel */
xskip -= hreduce;
shade = get_shade (x, y);
/* fprintf (outfile, "%s", charshade (shade)); */
outstring (charshade (shade), ct++);
#ifdef DEBUG
if (ct > ptr.width)
printf("Warning: %d chars on line\n", ct);
#endif DEBUG
} /* while xskip */
} /* for x */
/* print out the buffers */
for (i = 0; i < NBUFS; i++)
if (buf_used[i]){
buf[i][ct] = NULL;
/* first print the buffer */
fprintf (outfile, "%s", buf[i]);
/* Now do something to get printhead back to
* beginning of line, for overstriking.
*/
if (universal)
/* Universal printer output sends backspaces
* instead of a carriage return.
*/
for (j = 0; j < ct; j++)
fprintf (outfile, "\010");
else
/* each buffer followed by carriage return */
fprintf (outfile, "\015");
}
/* the end-of-line string */
fprintf(outfile,"%s", eol_string);
} /* while yskip */
} /* for y */
}else{
/* sideways print */
for (x = scr.xstart, xskip = 0.; x <= scr.xstop; x++){
xskip += 1.;
while (xskip > vreduce){
/* plot this line */
xskip -= vreduce;
/* Initialize the line buffers */
for (i = 0; i < NBUFS; i++)
buf_used[i] = 0;
for (y=scr.ystop, yskip=0., ct=0; y >= scr.ystart; y--){
yskip += 1.;
while (yskip > hreduce){
/* plot this pixel */
yskip -= hreduce;
shade = get_shade (x, y);
/* fprintf (outfile, "%s", charshade (shade)); */
outstring (charshade (shade), ct++);
} /* while yskip */
} /* for y */
/* print out the buffers */
for (i = 0; i < NBUFS; i++)
if (buf_used[i]){
buf[i][ct] = NULL;
/* first print the buffer */
fprintf (outfile, "%s", buf[i]);
/* Now do something to get printhead back to
* beginning of line, for overstriking.
*/
if (universal)
/* Universal printer output sends backspaces
* instead of a carriage return.
*/
for (j = 0; j < ct; j++)
fprintf (outfile, "\010");
else
/* each buffer followed by carriage return */
fprintf (outfile, "\015");
}
/* the end-of-line string */
fprintf(outfile,"%s", eol_string);
} /* while xskip */
} /* for x */
} /* if ! sideopt */
} /* printscreen */
/* eval_env: Evaluate the DWIP environment variable */
void eval_env()
{
char *getenv(), *index();
int eval_arg();
char *opts;
if (opts = getenv ("DWIP")){
while (opts){
if (eval_arg (opts)){
/* eval_arg thinks it's a filename; probably just an extra
* space between arguments, so ignore
*/
opts++;
}else{
/* advance to next argument */
opts = index (opts, ' ');
if (opts)
opts++;
}
} /* while */
} /* if opts */
} /* eval_env */
/* display_pic: Display an IFF picture on the screen, return 1 if
* successful, 0 if not. */
int display_pic (flnm)
char *flnm;
{
void help(), set_values(), free_planes(), put_ea_cmap();
struct ILBM_info *read_iff();
set_values();
if (scrn_alloc){
free_planes (&s_info->bitmap);
scrn_alloc = 0;
}
if ((s_info = read_iff(flnm, 0)) != NULL){
scrn_alloc = 1;
put_ea_cmap(&s_info->cmap, (1 << s_info->bitmap.Depth));
DwipRastPort.BitMap = &s_info->bitmap;
ClipBlit( &DwipRastPort, (long)0, (long)0,
&DwipScreen->RastPort, (long)s_info->header.x,
(long)s_info->header.y, (long)s_info->header.w,
(long)s_info->header.h, (long)COPY_MINTERM);
return (1);
}else
return (0);
} /* display_pic */
/* print_testpat: Print a simple test pattern across the page (5 lines) */
void print_testpat ()
{
char *charshade();
void outstring();
int ct, /* # shades of grey */
l, /* line # */
i, /* buffer # */
j; /* ctr for backspaces */
if (! fileopen){
if ((outfile = fopen (filename, "w")) == NULL){
printf("Couldn't open file %s for output\n", filename);
help (documentation);
}
fileopen = 1;
}
for (l = 0; l < 5; l++){
/* Initialize the line buffers */
for (i = 0; i < NBUFS; i++)
buf_used[i] = 0;
/* Output a continuous line of grey (black to white) */
for (ct = 0; ct < MAXSHADES; ct++)
outstring (charshade (ct), ct);
/* print out the buffers */
for (i = 0; i < NBUFS; i++){
if (buf_used[i]){
buf[i][ct] = NULL;
/* first print the buffer */
fprintf (outfile, "%s", buf[i]);
/* Now do something to get printhead back to
* beginning of line, for overstriking.
*/
if (universal)
/* Universal printer output sends backspaces
* instead of a carriage return.
*/
for (j = 0; j < ct; j++)
fprintf (outfile, "\010");
else
/* each buffer followed by carriage return */
fprintf (outfile, "\015");
} /* if buf_used */
} /* for i */
/* the end-of-line string */
fprintf(outfile,"%s", eol_string);
} /* for l */
} /* print_testpat */
main (argc, argv)
int argc;
char *argv[];
{
int eval_arg(), init_graph(), display_pic();
void eval_env(), dwip_cleanup(), printscreen(), print_testpat();
char *mktemp();
int i, /* index to args */
nfiles = 0; /* # input files read */
filename = mktemp ("RAM:dwXXXX");
eval_env();
/* Initialize graphics */
if (init_graph()){
dwip_cleanup();
exit(1);
}
/* parse the command line */
for (i=1; i<argc; i++){
#ifdef DEBUG
puts(argv[i]);
#endif DEBUG
if (eval_arg (argv[i])){
nfiles++;
if (display_pic (argv[i])){
if (! viewopt)
printscreen();
else
/* Viewing option: Just pause for specified # seconds */
Delay ((long)viewopt * 50);
free_planes (&s_info->bitmap);
scrn_alloc = 0;
}else /* if display_pic */
printf("dwip: Couldn't load %s as an IFF file\n", argv[i]);
} /* if eval_arg */
} /* for argv */
if (nfiles)
dwip_cleanup();
else if (testpat){
print_testpat();
dwip_cleanup();
}else{
printf ("dwip: No files specified.\n");
help (documentation);
}
#ifdef NEVER
/* This didn't work right, so I took it out. Seemed like a nice idea.
* If anybody knows what I did wrong, let me know. -kvc
*/
if (autopt)
execlp ("runback", "runback", "c:type", filename, "to", "PRT:",0);
#endif NEVER
} /* main */